package com.smart.manager.system.repository;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.smart.common.entities.constant.ExceptionTips;
import com.smart.common.entities.option.SelectOption;
import com.smart.common.entities.option.TreeOption;
import com.smart.common.exception.SmartException;
import com.smart.manager.system.entities.assembler.MenuMeta;
import com.smart.manager.system.entities.body.RSystemMenu;
import com.smart.manager.system.entities.body.RSystemModule;
import com.smart.manager.system.entities.enums.MenuAttribute;
import com.smart.manager.system.entities.models.SystemMenu;
import com.smart.manager.system.entities.models.query.QSystemMenu;
import io.ebean.DB;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 系统服务- 数据仓库
 *
 * @author xiaxuqiu
 * @date 2022/11/18
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class MenuRepository {

    private final ApiRepository apiRepository;


    public List<SystemMenu> getFullList() {
        List<SystemMenu> result = new QSystemMenu().order().sort.asc().findList();
        if (CollectionUtil.isNotEmpty(result)) {
            List<SelectOption> fullApiList = apiRepository.getDictList(false);
            for (SystemMenu menu : result) {
                List<SelectOption> collect = fullApiList.stream()
                        .filter(f -> menu.getApiTokens().contains(f.getValue()))
                        .collect(Collectors.toList());
                menu.setApiList(collect);
            }
        }
        return result;
    }


    /**
     * 修改数据
     *
     * @param id   id
     * @param data 修改后的数据
     */
    public void update(Long id, RSystemMenu.EditBody data) {
        SystemMenu record = new QSystemMenu().id.eq(id).setMaxRows(1).findOne();
        Assert.notNull(record, ExceptionTips.NOT_FOUND);
        BeanUtil.copyProperties(data, record);
        Objects.requireNonNull(record).update();
    }

    public int deleteByIds(List<Long> ids) {
        List<SystemMenu> list = new QSystemMenu().id.in(ids).findList();
        list.forEach(item -> {
            int childrenCount = this.getChildrenCount(item.getId());
            if (childrenCount > 0) {
                throw new SmartException(ExceptionTips.HAS_CHILDREN_DATA);
            }
        });
        return DB.deleteAll(list);
    }


    private int getChildrenCount(Long id) {
        return new QSystemMenu().parentId.eq(id).findCount();
    }

    public void add(RSystemMenu.EditBody data) {
        SystemMenu menu = BeanUtil.copyProperties(data, SystemMenu.class);
        menu.save();
    }


    /**
     * 根据模块创建目录
     *
     * @param body 身体
     */
    public void createByModule(RSystemModule.EditBody body) {
        SystemMenu menu = new SystemMenu();
        MenuMeta menuMeta = new MenuMeta();
        menuMeta.setTitle(body.getName()).setIcon(body.getIcon());
        menu.setAttribute(MenuAttribute.MODULE)
                .setParentId(0L)
                .setApiTokens(Collections.emptyList())
                .setApiList(Collections.emptyList())
                .setPath("/".concat(body.getCode()))
                .setComponent("LAYOUT")
                .setName(body.getCode())
                .setSort(body.getSort())
                .setMeta(menuMeta)
                .save();
    }


    /**
     * 获取树形结构数据字典
     *
     * @return {@code List<TreeOption>}
     */
    public List<TreeOption> getTreeOptions() {

        QSystemMenu qMenu = new QSystemMenu();
        qMenu.attribute.in(List.of(MenuAttribute.GROUP, MenuAttribute.MODULE))
                .select(QSystemMenu.Alias.id, QSystemMenu.Alias.meta, QSystemMenu.Alias.parentId)
                .orderBy().sort.desc();
        return qMenu.findStream()
                .map(m -> new TreeOption(m.getMeta().getTitle(), m.getId(), m.getParentId()))
                .collect(Collectors.toList());

    }


    public List<JSONObject> menuAndApiOptions() {
        List<SystemMenu> result = new QSystemMenu()
                .select(QSystemMenu.Alias.id, QSystemMenu.Alias.parentId, QSystemMenu.Alias.meta,
                        QSystemMenu.Alias.attribute,
                        QSystemMenu.Alias.apiTokens)
                .order().sort.asc().findList();
        if (CollectionUtil.isNotEmpty(result)) {
            List<SelectOption> fullApiList = apiRepository.getDictList(false);
            return result.stream().map(x -> {
                List<SelectOption> apiList = fullApiList.stream()
                        .filter(f -> x.getApiTokens().contains(f.getValue()))
                        .collect(Collectors.toList());
                return JSONUtil.createObj()
                        .putOnce("value", x.getId())
                        .putOnce("parent", x.getParentId())
                        .putOnce("attribute", x.getAttribute())
                        .putOnce("title", x.getMeta().getTitle())
                        .putOnce("apiList", apiList);
            }).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    public void updateByModule(RSystemModule.EditBody body) {
        SystemMenu systemMenu = new QSystemMenu().attribute.eq(MenuAttribute.MODULE).path.endsWith(body.getCode()).findOne();
        Assert.notNull(systemMenu, "修改失败 ,菜单信息不存在");
        MenuMeta meta = systemMenu.getMeta().setTitle(body.getName()).setIcon(body.getIcon());
        systemMenu.setMeta(meta).setSort(body.getSort()).update();
    }
}






